/**
 * 项目名：	Rumba Plan
 * 
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2007，所有权利保留。
 * 
 * 文件名：	RB_v00_r00.java
 * 模块说明：	
 * 修改历史：
 * 2007-2-28 - zyb - 创建。
 */
package com.hd123.rumba.upgrade.v20.r00;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;
import net.sf.hibernate.Transaction;

import org.apache.log4j.Logger;

import com.hd123.rumba.action.cartridge.ViewCartridgeAdvSys;
import com.hd123.rumba.action.cartridge.ViewCartridgeSystem;
import com.hd123.rumba.action.domain.ViewDomainAdvSys;
import com.hd123.rumba.action.domain.ViewDomainSystem;
import com.hd123.rumba.action.log.ViewActionLog;
import com.hd123.rumba.action.organization.ViewOrganizationAdvSys;
import com.hd123.rumba.action.organization.ViewOrganizationSystem;
import com.hd123.rumba.action.qt.ViewQuery;
import com.hd123.rumba.action.user.ViewRoleAdvSys;
import com.hd123.rumba.action.user.ViewRoleSystem;
import com.hd123.rumba.action.user.ViewUserAdvSys;
import com.hd123.rumba.action.user.ViewUserSystem;
import com.hd123.rumba.cartridge.CartRumba;
import com.hd123.rumba.cartridge.FVRumbaAdvSys;
import com.hd123.rumba.cartridge.biz.IBCartridgeMgr;
import com.hd123.rumba.domain.CDomain;
import com.hd123.rumba.domain.IDomain;
import com.hd123.rumba.domain.IDomainMgr;
import com.hd123.rumba.domain.biz.IBDomainMgr;
import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.organization.COrganization;
import com.hd123.rumba.runtime.HibernateSession;
import com.hd123.rumba.runtime.NamingMgr;
import com.hd123.rumba.runtime.OperateContext;
import com.hd123.rumba.upgrade.DBCommand;
import com.hd123.rumba.upgrade.Upgrade;
import com.hd123.rumba.user.CRole;
import com.hd123.rumba.user.CUser;
import com.hd123.rumba.user.IPermissionMgr;
import com.hd123.rumba.user.IUserMgr;
import com.hd123.rumba.util.Version;

/**
 * 安装升级: 0.0.0.0 -> 2.0.0.0
 * 
 * @author zyb
 * 
 */
public class RB_v00r00 extends Upgrade {

  public RB_v00r00() throws Exception {
    super();
    baseVersion = new Version("0.0.0.0");
    targetVersion = new Version("2.0.0.0");
    cartUuid = this.getCart(CartRumba.class).getUuid();
    logger = Logger.getLogger(this.getClass());
  }

  @Override
  protected void executeDdl() throws BusinessException {
    // 1、创建表结构
    logger.info("创建表结构");
    DBCommand cmd = new DBCommand();
    this.execFile(cmd, "rbcore_v00r00.sql");
    this.execFile(cmd, "rbextend_v00r00.sql");
  }

  @Override
  protected void executeData() throws BusinessException {
    // 2、创建root域
    logger.info("创建root域");
    try {
      createRootDomain();
    } catch (HibernateException e) {
      throw new BusinessException(e);
    }

    // 3、安装CartRumba
    // 3.1、保存CartRumba到数据库（版本号保持0.0.0.0，并设置upgrading=true）。
    // 3.2、添加CartRumba所包含的所有权限原子到数据库。
    logger.info("安装" + this.getCart(CartRumba.class).getCaption());
    IBCartridgeMgr cartMgr = (IBCartridgeMgr) NamingMgr.getInstance().lookupMgr(
        IBCartridgeMgr.class);
    try {
      cartMgr.saveCartridgeForInstallT(this.getCart(CartRumba.class).getUuid(), new Version(
          "0.0.0.0"));
      initPermissions();
    } catch (HibernateException e) {
      throw new BusinessException(e);
    }

    // 4、为CartRumba装载CartRumba的功能视图。
    // 4.1、装载FVRumbaSystemCommon。
    // 4.2、装载FVRumbaAdvSys。
    // 4.2.1、检查并创建root域的admin角色，添加所有权限到admin角色。
    // 4.2.2、检查并创建root域的admin用户，设置拥有admin角色。
    logger.info("为CartRumba装载功能视图");
    IBDomainMgr bdmMgr = (IBDomainMgr) NamingMgr.getInstance().lookupMgr(IBDomainMgr.class);
    IDomainMgr dm = (IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class);
    IUserMgr um = (IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class);
    try {
      bdmMgr.loadCFVsToDomainT(this.getCFV(FVRumbaAdvSys.class).getUuid(), dm.getRootDomain()
          .getUuid(), new OperateContext(um.getSysUser()), dm.getRootDomain().getOca());
      initPermissions();
    } catch (HibernateException e) {
      throw new BusinessException(e);
    } catch (InterruptedException e) {
      throw new BusinessException(e);
    }
  }

  private void createRootDomain() throws HibernateException, BusinessException {
    IDomainMgr domainMgr = (IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class);
    IUserMgr userMgr = (IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class);

    Session session = HibernateSession.getSession();
    Transaction tx = session.beginTransaction();
    try {
      IDomain root = domainMgr.getDomainByCode("ROOT");
      if (root == null) {
        root = domainMgr.createDomain(null, "ROOT", "根域");
        root.setState(CDomain.VALUE_STATE_NORMAL);
        domainMgr.saveDomain(root, new OperateContext(userMgr.getSysUser()), root.getOca());
      }
      tx.commit();
    } catch (BusinessException e) {
      tx.rollback();
      throw e;
    } catch (HibernateException e) {
      tx.rollback();
      throw e;
    } finally {
      session.flush();
    }

    // 清除根域的内存缓冲
    domainMgr.clearRootDomainCache();
  }

  private void initPermissions() throws HibernateException, BusinessException {
    IPermissionMgr permMgr = (IPermissionMgr) NamingMgr.getInstance().lookupMgr(
        IPermissionMgr.class);
    try {
      permMgr.initPermissionsT(CDomain.class);
      permMgr.initPermissionsT(COrganization.class);
      permMgr.initPermissionsT(CUser.class);
      permMgr.initPermissionsT(CRole.class);
      permMgr.initPermissionsT(ViewQuery.class);
      permMgr.initPermissionsT(ViewOrganizationAdvSys.class);
      permMgr.initPermissionsT(ViewOrganizationSystem.class);
      permMgr.initPermissionsT(ViewDomainAdvSys.class);
      permMgr.initPermissionsT(ViewDomainSystem.class);
      permMgr.initPermissionsT(ViewCartridgeAdvSys.class);
      permMgr.initPermissionsT(ViewCartridgeSystem.class);
      permMgr.initPermissionsT(ViewRoleAdvSys.class);
      permMgr.initPermissionsT(ViewRoleSystem.class);
      permMgr.initPermissionsT(ViewUserAdvSys.class);
      permMgr.initPermissionsT(ViewUserSystem.class);
      permMgr.initPermissionsT(ViewActionLog.class);
    } catch (Exception e) {
      if (e instanceof HibernateException)
        throw (HibernateException) e;
      else
        throw new BusinessException(e);
    }
  }
}
